<?php

namespace doujunyu\utility;

/** 类工具类
 * 类下面所有的方法
 * 随机字符串 ->get_random_string
 * 处理流量格式 -> bytes
 * 处理流量转换 -> bit_get_gb
 * php 输出视频流 -> video
 * 求两个已知经纬度之间的距离,单位为米 -> coordinate_distance
 * 生成验证码 -> generate_captcha
 * 根据传入的年月获取一个一维数的数组 -> get_date_list
 * 根据传入的年月获取一个一维数的数组 -> get_date_full_list
 * 富文本接口返回 -> image_url
 */

class SelfUtility
{

    /**随机字符串
     * @param int $len //长度
     * @param null $chars //随机的值
     * @return string
     */
    public static function get_random_string($len, $chars=null)
    {
        if (is_null($chars)) {
            $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        }
        mt_srand(10000000*(double)microtime());
        for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $lc)];
        }
        return $str;
    }

    /**处理流量格式
     * $size 单位是kb
     */
    public static function bytes($size) {
        $units = array(' KB', ' MB', ' GB', ' TB');
        for ($i = 0; $size >= 1024 && $i < 3; $i++) $size /= 1024;
        return round($size, 2).$units[$i];
    }

    /**处理流量转换
     * $size 单位是k
     */
    public static function bit_get_gb($size){
        return round($size/(1024 * 1024 * 1024), 2);
    }

    /**php 输出视频流
     * @param $file
     */
    public static function video($file){
        ini_set('memory_limit','512M');
        header("Content-type: video/mp4");
        header("Accept-Ranges: bytes");

        ob_start();// ------ 开启缓冲区
        $size = filesize($file);

        if(isset($_SERVER['HTTP_RANGE'])){
            header("HTTP/1.1 206 Partial Content");
            list($name, $range) = explode("=", $_SERVER['HTTP_RANGE']);
            list($begin, $end) =explode("-", $range);
            if($end == 0) $end = $size - 1;
        }
        else {
            $begin = 0; $end = $size - 1;
        }

        header("Content-Length: " . ($end - $begin + 1));
        header("Content-Disposition: filename=".basename($file));
        header("Content-Range: bytes ".$begin."-".$end."/".$size);

        try {
            $fp = fopen($file, 'r');
        } catch (\Exception $e) {
            echo $e->getTraceAsString();exit;
        }
        fseek($fp, $begin);
        $contents = '';

        while(!feof($fp)) {
            $p = min(1024, $end - $begin + 1);
            //$begin += $p;
            $contents .= fread($fp, $p);
            //echo fread($fp, $p);
        }
        //$contents = ltrim($contents, "\XEF\XBB\XBF");
        ob_end_clean();            // ------ 清除缓冲区
        ob_clean();
        //$contents = substr($contents, 3);
        fclose($fp);

        exit($contents);
    }

    /** 求两个已知经纬度之间的距离,单位为米
     * @param $longitude1 经度
     * @param $latitude1 纬度
     * @param $longitude2 经度
     * @param $latitude2 纬度
     * @return float 距离，单位米
     **/
    public static function coordinate_distance($longitude1, $latitude1, $longitude2, $latitude2) {
        $lng1 = $longitude1;//经度
        $lat1 = $latitude1;//维度
        $lng2 = $longitude2;//经度
        $lat2 = $latitude2;//维度
        //将角度转为狐度

        $radLat1=deg2rad($lat1);//deg2rad()函数将角度转换为弧度

        $radLat2=deg2rad($lat2);

        $radLng1=deg2rad($lng1);

        $radLng2=deg2rad($lng2);

        $a=$radLat1-$radLat2;

        $b=$radLng1-$radLng2;

        $s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137*1000;

        return round($s, 2);

    }

    /**生成验证码
     * $font = ROOT_PATH.'/vendor/topthink/think-captcha/assets/ttfs/6.ttf';
     */
    public static function generate_captcha($code, $width = 240, $height = 80, $font='') {
        
        $_SESSION["captcha_code"] = $code;
        $codeLength = strlen($code);
        
        // 创建图像
        $image = imagecreatetruecolor($width, $height);
        
        // 颜色定义
        $bgColor = imagecolorallocate($image, 245, 245, 245); // 浅灰色背景
        $borderColor = imagecolorallocate($image, 220, 220, 220); // 浅边框
        
        // 文字颜色数组
        $textColors = [
            imagecolorallocate($image, 70, 130, 180),   // 钢蓝色
            imagecolorallocate($image, 220, 20, 60),    // 深红色
            imagecolorallocate($image, 34, 139, 34),    // 森林绿
            imagecolorallocate($image, 255, 140, 0),    // 橙色
        ];
        
        // 填充背景
        imagefilledrectangle($image, 0, 0, $width, $height, $bgColor);
        imagerectangle($image, 0, 0, $width-1, $height-1, $borderColor);
        
        // 添加渐变背景效果
        for ($i = 0; $i < $width; $i += 5) {
            $color = imagecolorallocate($image, rand(230, 240), rand(230, 240), rand(230, 240));
            imageline($image, $i, 0, $i, $height, $color);
        }
        
        // 添加干扰元素
        for ($i = 0; $i < 3; $i++) {
            $color = imagecolorallocatealpha($image, rand(100, 200), rand(100, 200), rand(100, 200), 60);
            imageline($image, rand(0, $width/3), rand(0, $height), rand($width*2/3, $width), rand(0, $height), $color);
        }
        
        for ($i = 0; $i < 100; $i++) {
            $color = imagecolorallocatealpha($image, rand(0, 255), rand(0, 255), rand(0, 255), 70);
            imagesetpixel($image, rand(0, $width), rand(0, $height), $color);
        }
        
        /**************** 均匀分布的数字 ****************/
        $fontSize = 28;
        
        $fontFile = $font; // 请确保字体文件存在
        
        // 计算每个字符的可用空间
        $charWidth = $width / $codeLength;
        
        // 绘制每个字符
        for ($i = 0; $i < $codeLength; $i++) {
            $char = substr($code, $i, 1);
            
            // 计算当前字符的边界框
            $bbox = imagettfbbox($fontSize, 0, $fontFile, $char);
            $charHeight = $bbox[1] - $bbox[7];
            
            // 计算字符位置 - 均匀分布
            $x = $i * $charWidth + ($charWidth - ($bbox[2] - $bbox[0])) / 2;
            $y = ($height - $charHeight) / 2 + $charHeight;
            
            // 轻微随机角度和垂直位置
            $angle = rand(-5, 5);
            $yOffset = rand(-3, 3);
            
            // 文字阴影
            imagettftext($image, $fontSize, $angle, $x+1, $y+$yOffset+1, 
                    imagecolorallocate($image, 180, 180, 180), $fontFile, $char);
            
            // 主文字
            imagettftext($image, $fontSize, $angle, $x, $y+$yOffset, 
                    $textColors[array_rand($textColors)], $fontFile, $char);
        }
        
        // 输出图像
        header('Content-Type: image/png');
        imagepng($image);
        imagedestroy($image);
    }

    //根据传入的年月获取一个一维数的数组
    public static function get_date_list($y, $m){
        $days = range(1, date('t', mktime(0, 0, 0, $m, 1, $y)));
        return array_map(function($day) {
            return sprintf('%02d', $day);
        }, $days);
    }
    //根据传入的年月获取一个一维数的数组
    public static function get_date_full_list($year, $month){
        return array_map(fn($day) => "$year-" . str_pad($month, 2, '0', STR_PAD_LEFT) . "-" . str_pad($day, 2, '0', STR_PAD_LEFT), range(1, date('t', strtotime("$year-$month-01"))));
    }

    /**富文本接口返回
     */
    public function image_url($content)
    {
        $reg = strpos($content, 'http');
        if (empty($reg)) {
            $url = "http://" . $_SERVER['SERVER_NAME'];
        } else {
            $url = '';
        }
        $pregRule = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.jpg|\.jpeg|\.png|\.gif|\.bmp]))[\'|\"].*?[\/]?>/";
        $content = preg_replace($pregRule, '<img src="' . $url . '${1}" style="max-width:100%">', $content);
        return $content;
    }

}